package com.foogui.bootrabbitmq.delay;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


/**
 * rabbitmq配置，延迟消息
 *
 * @author Foogui
 * @date 2023/07/07
 */
@Configuration
public class DelayConfig {

    // 延迟交换机名称
    public static final String DELAY_EXCHANGE_NAME = "delay.exchange";

    // 延迟队列名称
    // 5s延迟的队列
    public static final String DELAY_QUEUE_5S_NAME = "delay.queue.5s";
    // 15min延迟的队列
    public static final String DELAY_QUEUE_15M_NAME = "delay.queue.15m";

    // 延迟队列路由规则
    // 5s延迟的队列
    public static final String DELAY_QUEUE_5S_ROUTING_KEY = "delay.queue.5s.routingKey";
    // /15min延迟的队列
    public static final String DELAY_QUEUE_15M_ROUTING_KEY = "delay.queue.15m.routingKey";
    // 死信交换机名称
    public static final String DEAD_LETTER_EXCHANGE = "dead.queue.x-dead-letter-exchange";
    public static final String DEAD_LETTER_5S_QUEUE_NAME = "dead.queue.5s";
    public static final String DEAD_LETTER_15M_QUEUE_NAME = "dead.queue.15m";
    // 死信队列5S路由规则
    public static final String DEAD_LETTER_QUEUE_5S_ROUTING_KEY = "dead.queue.5s.x-dead-letter-routing-key";
    // 死信队列15M路由规则
    public static final String DEAD_LETTER_QUEUE_15M_ROUTING_KEY = "dead.queue.15m.x-dead-letter-routing-key";


    @Bean
    DirectExchange delayExchange() {
        return new DirectExchange(DELAY_EXCHANGE_NAME, true, false);
    }

    @Bean
    public Queue delayQueue5S() {
        Map<String, Object> args = new HashMap<>(2);
        // x-dead-letter-exchange这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        // x-dead-letter-routing-key这里声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_5S_ROUTING_KEY);
        // x-message-ttl声明队列的TTL,消息5秒后过期后转发到死信队列
        args.put("x-message-ttl", 5 * 1000);
        // 声明5秒过期的延迟队列，并将该队列绑定到死信交换机
        return QueueBuilder.durable(DELAY_QUEUE_5S_NAME).withArguments(args).build();
    }

    @Bean
    public Queue delayQueue15M() {
        Map<String, Object> args = new HashMap<>(2);
        // x-dead-letter-exchange这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        // x-dead-letter-routing-key这里声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_15M_ROUTING_KEY);
        // x-message-ttl声明队列的TTL,消息5秒后过期后转发到死信队列
        args.put("x-message-ttl", 60 * 1000 * 15);
        // 声明5秒过期的延迟队列，并将该队列绑定到死信交换机
        return QueueBuilder.durable(DELAY_QUEUE_15M_NAME).withArguments(args).build();
    }




    /**
     * 绑定exchange和queue
     *
     * @return {@link Binding}
     */
    @Bean
    Binding bindingDelay5S() {
        return BindingBuilder.bind(delayQueue5S()).to(delayExchange()).with(DELAY_QUEUE_5S_ROUTING_KEY);
    }

    @Bean
    Binding bindingDelay15M() {
        return BindingBuilder.bind(delayQueue15M()).to(delayExchange()).with(DELAY_QUEUE_15M_ROUTING_KEY);
    }


    //    -----------------------------死信交换机声明----------------------------

    @Bean
    DirectExchange deadExchange() {
        return new DirectExchange(DEAD_LETTER_EXCHANGE, true, false);
    }

    @Bean
    public Queue deadQueue5S() {
        return QueueBuilder.durable(DEAD_LETTER_5S_QUEUE_NAME).build();
    }

    @Bean
    public Queue deadQueue15M() {
        return QueueBuilder.durable(DEAD_LETTER_15M_QUEUE_NAME).build();
    }

    @Bean
    Binding bindingDead5S() {
        return BindingBuilder.bind(deadQueue5S()).to(deadExchange()).with(DEAD_LETTER_QUEUE_5S_ROUTING_KEY);
    }

    @Bean
    Binding bindingDead15M() {
        return BindingBuilder.bind(deadQueue15M()).to(deadExchange()).with(DEAD_LETTER_QUEUE_15M_ROUTING_KEY);
    }
}
